package fr.vince.java.rps_game;

import java.util.ArrayList;
import java.util.List;

import org.testng.annotations.AfterClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import org.testng.annotations.BeforeClass;
import org.testng.AssertJUnit;
import org.testng.Assert;

public class NewTest {
	@Test(dataProvider = "win")
	public void testWinPlay(RPSEnum p1, RPSEnum p2) {
		RockPaperScissors obj = new RockPaperScissors();
		AssertJUnit.assertEquals(obj.play(p1, p2) == Result.WIN ? true : false,
				true);
	}

	@Test(dataProvider = "tie")
	void testTiePlay(RPSEnum p1, RPSEnum p2) {
		RockPaperScissors obj = new RockPaperScissors();
		AssertJUnit.assertEquals(obj.play(p1, p2) == Result.TIE ? true : false,
				true);
	}

	@Test(dataProvider = "lost")
	void testLostPlay(RPSEnum p1, RPSEnum p2) {
		RockPaperScissors obj = new RockPaperScissors();
		AssertJUnit.assertEquals(
				obj.play(p1, p2) == Result.LOST ? true : false, true);
	}

	@BeforeClass
	public void beforeClass() {
	}

	@AfterClass
	public void afterClass() {
	}

	@DataProvider(name = "win")
	public Object[][] createWinData() {
		return new Object[][] { { RPSEnum.PAPER, RPSEnum.ROCK },
				{ RPSEnum.ROCK, RPSEnum.SCISSORS },
				{ RPSEnum.SCISSORS, RPSEnum.PAPER } };
	}

	@DataProvider(name = "tie")
	public Object[][] createTieData() {
		return new Object[][] { { RPSEnum.PAPER, RPSEnum.PAPER },
				{ RPSEnum.ROCK, RPSEnum.ROCK },
				{ RPSEnum.SCISSORS, RPSEnum.SCISSORS } };
	}

	@DataProvider(name = "lost")
	public Object[][] createLostData() {
		return new Object[][] { { RPSEnum.PAPER, RPSEnum.SCISSORS },
				{ RPSEnum.ROCK, RPSEnum.PAPER },
				{ RPSEnum.SCISSORS, RPSEnum.ROCK } };
	}

	@Test
	/* (dataProvider = "lost") */
	void testGame() {
		Player p1 = new Player("P1");
		Player p2 = new Player("P2");
		RockPaperScissors obj = new RockPaperScissors();
		AssertJUnit
				.assertEquals(
						(obj.play(p1, p2) == Result.LOST && p1.getScore() < p2.getScore())
								|| (obj.play(p1, p2) == Result.TIE && p1
										.getScore() == p2.getScore())
								|| (obj.play(p1, p2) == Result.WIN && p1
										.getScore() > p2.getScore()) ? true
								: false, true);
	}

	@Test
	void testGameWin() {
		List<RPSEnum> moves_p1 = new ArrayList<RPSEnum>();
		moves_p1.add(RPSEnum.ROCK);
		moves_p1.add(RPSEnum.PAPER);
		moves_p1.add(RPSEnum.SCISSORS);
		moves_p1.add(RPSEnum.ROCK);
		moves_p1.add(RPSEnum.PAPER);
		moves_p1.add(RPSEnum.SCISSORS);
		moves_p1.add(RPSEnum.ROCK);
		moves_p1.add(RPSEnum.PAPER);
		moves_p1.add(RPSEnum.SCISSORS);
		moves_p1.add(RPSEnum.ROCK);
		
		List<RPSEnum> moves_p2 = new ArrayList<RPSEnum>();
		moves_p2.add(RPSEnum.ROCK);
		moves_p2.add(RPSEnum.PAPER);
		moves_p2.add(RPSEnum.SCISSORS);
		moves_p2.add(RPSEnum.ROCK);
		moves_p2.add(RPSEnum.PAPER);
		moves_p2.add(RPSEnum.SCISSORS);
		moves_p2.add(RPSEnum.ROCK);
		moves_p2.add(RPSEnum.PAPER);
		moves_p2.add(RPSEnum.SCISSORS);
		moves_p2.add(RPSEnum.SCISSORS);

		Player p1 = new Player("P1",moves_p1);
		Player p2  = new Player("P2",moves_p2);
		RockPaperScissors obj = new RockPaperScissors();
		AssertJUnit.assertEquals(obj.play(p1, p2) == Result.WIN ? true : false,
				true);
	}

	@Test
	void testGameLoose() {
		List<RPSEnum> moves_p1 = new ArrayList<RPSEnum>();
		moves_p1.add(RPSEnum.ROCK);
		moves_p1.add(RPSEnum.PAPER);
		moves_p1.add(RPSEnum.SCISSORS);
		moves_p1.add(RPSEnum.ROCK);
		moves_p1.add(RPSEnum.PAPER);
		moves_p1.add(RPSEnum.SCISSORS);
		moves_p1.add(RPSEnum.ROCK);
		moves_p1.add(RPSEnum.PAPER);
		moves_p1.add(RPSEnum.SCISSORS);
		moves_p1.add(RPSEnum.ROCK);
		
		List<RPSEnum> moves_p2 = new ArrayList<RPSEnum>();
		moves_p2.add(RPSEnum.ROCK);
		moves_p2.add(RPSEnum.PAPER);
		moves_p2.add(RPSEnum.SCISSORS);
		moves_p2.add(RPSEnum.ROCK);
		moves_p2.add(RPSEnum.PAPER);
		moves_p2.add(RPSEnum.SCISSORS);
		moves_p2.add(RPSEnum.ROCK);
		moves_p2.add(RPSEnum.PAPER);
		moves_p2.add(RPSEnum.SCISSORS);
		moves_p2.add(RPSEnum.PAPER);

		Player p1 = new Player("P1",moves_p1);
		Player p2  = new Player("P2",moves_p2);
		RockPaperScissors obj = new RockPaperScissors();
		AssertJUnit.assertEquals(
				obj.play(p1, p2) == Result.LOST ? true : false, true);
	}

	@Test
	void testGameTie() {
		List<RPSEnum> moves_p1 = new ArrayList<RPSEnum>();
		moves_p1.add(RPSEnum.ROCK);
		moves_p1.add(RPSEnum.PAPER);
		moves_p1.add(RPSEnum.SCISSORS);
		moves_p1.add(RPSEnum.ROCK);
		moves_p1.add(RPSEnum.PAPER);
		moves_p1.add(RPSEnum.SCISSORS);
		moves_p1.add(RPSEnum.ROCK);
		moves_p1.add(RPSEnum.PAPER);
		moves_p1.add(RPSEnum.SCISSORS);
		moves_p1.add(RPSEnum.ROCK);
		
		List<RPSEnum> moves_p2 = new ArrayList<RPSEnum>();
		moves_p2.add(RPSEnum.ROCK);
		moves_p2.add(RPSEnum.PAPER);
		moves_p2.add(RPSEnum.SCISSORS);
		moves_p2.add(RPSEnum.ROCK);
		moves_p2.add(RPSEnum.PAPER);
		moves_p2.add(RPSEnum.SCISSORS);
		moves_p2.add(RPSEnum.ROCK);
		moves_p2.add(RPSEnum.PAPER);
		moves_p2.add(RPSEnum.SCISSORS);
		moves_p2.add(RPSEnum.ROCK);

		Player p1 = new Player("P1",moves_p1);
		Player p2  = new Player("P2",moves_p2);
		RockPaperScissors obj = new RockPaperScissors();
		AssertJUnit.assertEquals(obj.play(p1, p2) == Result.TIE ? true : false,
				true);
	}
	
	@Test
	void testScore1() {
		List<RPSEnum> moves_p1 = new ArrayList<RPSEnum>();
		moves_p1.add(RPSEnum.ROCK);
		moves_p1.add(RPSEnum.PAPER);
		moves_p1.add(RPSEnum.SCISSORS);
		moves_p1.add(RPSEnum.ROCK);
		moves_p1.add(RPSEnum.PAPER);
		moves_p1.add(RPSEnum.SCISSORS);
		moves_p1.add(RPSEnum.ROCK);
		moves_p1.add(RPSEnum.PAPER);
		moves_p1.add(RPSEnum.SCISSORS);
		moves_p1.add(RPSEnum.ROCK);
		
		List<RPSEnum> moves_p2 = new ArrayList<RPSEnum>();
		moves_p2.add(RPSEnum.ROCK);
		moves_p2.add(RPSEnum.PAPER);
		moves_p2.add(RPSEnum.SCISSORS);
		moves_p2.add(RPSEnum.ROCK);
		moves_p2.add(RPSEnum.PAPER);
		moves_p2.add(RPSEnum.SCISSORS);
		moves_p2.add(RPSEnum.ROCK);
		moves_p2.add(RPSEnum.PAPER);
		moves_p2.add(RPSEnum.SCISSORS);
		moves_p2.add(RPSEnum.ROCK);

		Player p1 = new Player("P1",moves_p1);
		Player p2  = new Player("P2",moves_p2);
		RockPaperScissors obj = new RockPaperScissors();
		obj.play(p1, p2);
		AssertJUnit.assertEquals( (p1.getScore() == 10 &&  p2.getScore()==10)? true : false,
				true);
	}
	
	@Test
	void testScore2() {
		List<RPSEnum> moves_p1 = new ArrayList<RPSEnum>();
		moves_p1.add(RPSEnum.ROCK); //+1
		moves_p1.add(RPSEnum.PAPER); 
		moves_p1.add(RPSEnum.SCISSORS); 
		moves_p1.add(RPSEnum.ROCK); 
		moves_p1.add(RPSEnum.PAPER);
		moves_p1.add(RPSEnum.SCISSORS);
		moves_p1.add(RPSEnum.ROCK);
		moves_p1.add(RPSEnum.PAPER);
		moves_p1.add(RPSEnum.SCISSORS); //+1
		moves_p1.add(RPSEnum.ROCK);
		
		List<RPSEnum> moves_p2 = new ArrayList<RPSEnum>();
		moves_p2.add(RPSEnum.SCISSORS);
		moves_p2.add(RPSEnum.PAPER); 
		moves_p2.add(RPSEnum.SCISSORS); 
		moves_p2.add(RPSEnum.ROCK);
		moves_p2.add(RPSEnum.PAPER);
		moves_p2.add(RPSEnum.SCISSORS);
		moves_p2.add(RPSEnum.ROCK);
		moves_p2.add(RPSEnum.PAPER);
		moves_p2.add(RPSEnum.PAPER);
		moves_p2.add(RPSEnum.ROCK);

		Player p1 = new Player("P1",moves_p1);
		Player p2  = new Player("P2",moves_p2);
		RockPaperScissors obj = new RockPaperScissors();
		obj.play(p1, p2);
		AssertJUnit.assertEquals( (p1.getScore() == 10 &&  p2.getScore()==8)? true : false,
				true);
	}
	
	@Test
	void testScore3() {
		List<RPSEnum> moves_p1 = new ArrayList<RPSEnum>();
		moves_p1.add(RPSEnum.ROCK);
		moves_p1.add(RPSEnum.PAPER);
		moves_p1.add(RPSEnum.SCISSORS);
		moves_p1.add(RPSEnum.ROCK);
		moves_p1.add(RPSEnum.PAPER);
		moves_p1.add(RPSEnum.SCISSORS);
		moves_p1.add(RPSEnum.ROCK);
		moves_p1.add(RPSEnum.PAPER);
		moves_p1.add(RPSEnum.SCISSORS);
		moves_p1.add(RPSEnum.ROCK);
		
		List<RPSEnum> moves_p2 = new ArrayList<RPSEnum>();
		moves_p2.add(RPSEnum.SCISSORS);
		moves_p2.add(RPSEnum.ROCK);
		moves_p2.add(RPSEnum.PAPER);
		moves_p2.add(RPSEnum.SCISSORS);
		moves_p2.add(RPSEnum.ROCK);
		moves_p2.add(RPSEnum.PAPER);
		moves_p2.add(RPSEnum.SCISSORS);
		moves_p2.add(RPSEnum.ROCK);
		moves_p2.add(RPSEnum.PAPER);
		moves_p2.add(RPSEnum.SCISSORS);

		Player p1 = new Player("P1",moves_p1);
		Player p2  = new Player("P2",moves_p2);
		RockPaperScissors obj = new RockPaperScissors();
		obj.play(p1, p2);
		AssertJUnit.assertEquals( (p1.getScore() == 10 &&  p2.getScore()==0) ? true : false,
				true);
	}
}
